package com.dong.code;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Set;

public class MybatisCode {
    private static final String PO_NAME = "ApplySkuPO";
    private static final String QUERYPO_TYPE = "ApplySkuQueryPO";
    private static final String TABLE_NAME = "pop_z_center_apply_sku";
    private static final List<String> COLUMN_LIST = Lists.newArrayList(
            "id,BIGINT",
            "venderId,BIGINT",
            "activityId,BIGINT",
            "applyId,BIGINT",
            "skuId,BIGINT",
            "skuName,VARCHAR",
            "skuPrice,DECIMAL",
            "wareId,BIGINT",
            "creator,VARCHAR",
            "modifier,VARCHAR",
            "createTime,BIGINT",
            "modifiedTime,BIGINT",
            "lastOperationTime,BIGINT",
            "hasDel,BOOLEAN"
    );

    public static void main(String[] args) {
        // 打印表头
        printXmlHeader();

        printResultMap();
        printBaseColumnList();
        printInsert();
        printBatchInsert();
        printQueryById();
        printQueryByIds();
        printDeleteyId();
        printQueryList();
        printCount();
        printBaseWhere();
        printUpdateById();

        // 打印表尾
        printXmlFooter();
    }

    private static void printXmlHeader() {
        System.out.printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n" +
                "<mapper namespace=\"%s\">\n", PO_NAME);
    }

    private static void printXmlFooter() {
        System.out.print("</mapper>");
    }

    private static String getColumnType(String columnType) {
        if ("INT".equals(columnType)) {
            return "INTEGER";
        }
        return columnType;
    }

    private static void printResultMap() {
        System.out.printf("\t<resultMap id=\"BaseResultMap\" type=\"%s\">\n", PO_NAME);
        for (String column : COLUMN_LIST) {
            if (StringUtils.isBlank(column)) {
                throw new RuntimeException("printResultMap");
            }
            String[] array = column.split(",");
            String columnName = array[0];
            String columnType = getColumnType(array[1]);

            if ("id".equals(columnName)) {
                System.out.printf("\t\t<id column=\"%s\" jdbcType=\"%s\" property=\"%s\"/>%n", columnName, columnType, columnName);
            } else {
                System.out.printf("\t\t<result column=\"%s\" jdbcType=\"%s\" property=\"%s\"/>%n", columnName, columnType, columnName);
            }
        }
        System.out.print("\t</resultMap>\n\n");
    }

    private static void printBaseColumnList() {
        System.out.print("\t<sql id=\"Base_Column_List\">\n");
        for (int i = 0, size = COLUMN_LIST.size(); i < size; i++) {
            String[] array = COLUMN_LIST.get(i).split(",");
            String columnName = array[0];

            System.out.printf("\t\t%s%s\n", columnName, i < size - 1 ? "," : "");
        }
        System.out.print("\t</sql>\n\n");
    }

    private static void printInsert() {
        StringBuilder sb1 = new StringBuilder("\t\tinsert into ").append(TABLE_NAME).append(" (\n");
        StringBuilder sb2 = new StringBuilder("\t\tvalues (\n");

        System.out.printf("\t<insert id=\"insert\" parameterType=\"%s\">\n", PO_NAME);
        for (int i = 0, size = COLUMN_LIST.size(); i < size; i++) {
            String[] array = COLUMN_LIST.get(i).split(",");
            String columnName = array[0];
            String columnType = getColumnType(array[1]);

            String fenge = i < size - 1 ? ",\n" : "";

            sb1.append("\t\t\t").append(columnName).append(fenge);
            sb2.append("\t\t\t").append("#{").append(columnName).append(", jdbcType=").append(columnType).append("}").append(fenge);
        }
        System.out.print(sb1 + ")\n");
        System.out.print(sb2 + ")\n");
        System.out.print("\t</insert>\n\n");
    }

    private static void printBatchInsert() {
        System.out.printf("\t<insert id=\"batchInsert\" parameterType=\"%s\">\n", PO_NAME);

        StringBuilder sb1 = new StringBuilder("\t\tinsert into ").append(TABLE_NAME).append(" (\n");
        StringBuilder sb2 = new StringBuilder("\t\tvalues\n \t\t<foreach collection=\"list\" item=\"item\" separator=\",\">").append("\n\t\t\t(\n");
        for (int i = 0, size = COLUMN_LIST.size(); i < size; i++) {
            String[] array = COLUMN_LIST.get(i).split(",");
            String columnName = array[0];
            String columnType = getColumnType(array[1]);

            String fenge = i < size - 1 ? ",\n" : "";

            sb1.append("\t\t\t").append(columnName).append(fenge);
            sb2.append("\t\t\t").append("#{item.").append(columnName).append(", jdbcType=").append(columnType).append("}").append(fenge);
        }
        System.out.print(sb1 + ")\n");
        System.out.print(sb2 + ")\n");
        System.out.print("\t\t</foreach>\n");
        System.out.print("\t</insert>\n\n");
    }

    private static void printQueryById() {
        System.out.printf("\t<select id=\"queryById\" parameterType=\"java.lang.Long\" resultMap=\"BaseResultMap\">\n" +
                "        select\n" +
                "        <include refid=\"Base_Column_List\"/>\n" +
                "        from %s\n" +
                "        where id = #{id}\n" +
                "    </select>\n\n", TABLE_NAME);
    }

    private static void printQueryByIds() {
        System.out.printf("\t<select id=\"queryByIds\" parameterType=\"java.util.List\" resultMap=\"BaseResultMap\">\n" +
                "        select\n" +
                "        <include refid=\"Base_Column_List\"/>\n" +
                "        from %s\n" +
                "        where id in\n" +
                "        <foreach collection=\"ids\" open=\"(\" separator=\",\" close=\")\" item=\"item\">\n" +
                "            #{item}\n" +
                "        </foreach>\n" +
                "    </select>\n\n", TABLE_NAME);
    }

    private static void printDeleteyId() {
        System.out.printf("\t<update id=\"deleteyId\" parameterType=\"java.lang.Long\">\n" +
                "        update %s\n" +
                "        set hasDel            = false,\n" +
                "            modifiedTime      = UNIX_TIMESTAMP() * 1000,\n" +
                "            lastOperationTime = UNIX_TIMESTAMP() * 1000\n" +
                "        where id = #{id}\n" +
                "    </update>\n\n", TABLE_NAME);
    }

    private static void printQueryList() {
        System.out.printf("\t<select id=\"queryList\" parameterType=\"%s\" resultMap=\"BaseResultMap\">\n" +
                "        select\n" +
                "        <include refid=\"Base_Column_List\"/>\n" +
                "        from %s\n" +
                "        <include refid=\"Base_Where\"/>\n" +
                "        <if test=\"orderList != null and orderList.size > 0\">\n" +
                "            order by\n" +
                "            <foreach collection=\"orderList\" open=\"\" separator=\",\" close=\"\" item=\"item\">\n" +
                "                ${item.sortKey} ${item.sortType}\n" +
                "            </foreach>\n" +
                "        </if>\n" +
                "        <if test=\"skipSize != null and pageSize != null\">\n" +
                "            limit #{skipSize}, #{pageSize}\n" +
                "        </if>\n" +
                "    </select>\n\n", QUERYPO_TYPE, TABLE_NAME);
    }

    private static void printCount() {
        System.out.printf("\t<select id=\"count\" parameterType=\"%s\" resultType=\"java.lang.Long\">\n" +
                "        select count(*)\n" +
                "        from %s\n" +
                "        <include refid=\"Base_Where\"/>\n" +
                "    </select>\n\n", QUERYPO_TYPE, TABLE_NAME);
    }

    private static void printBaseWhere() {
        System.out.printf("\t<sql id=\"Base_Where\">\n");
        System.out.printf("\t\t<where>\n");

        for (int i = 0, size = COLUMN_LIST.size(); i < size; i++) {
            String[] array = COLUMN_LIST.get(i).split(",");
            String columnName = array[0];
            String queryColumnName = convertQueryColumnName(columnName);
//            String columnType = getColumnType(array[1]);

            if (blackQueryColumnSet.contains(columnName)) {
                continue;
            }

            System.out.printf("\t\t\t<if test=\"%s != null\">\n" +
                    "                AND %s = #{%s}\n" +
                    "            </if>\n", queryColumnName, columnName, queryColumnName);
        }
        System.out.printf("\t\t</where>\n");
        System.out.printf("\t</sql>\n\n");
    }

    private static final Set<String> blackQueryColumnSet = Sets.newHashSet(
            "createTime",
            "modifiedTime",
            "lastOperationTime");

    private static String convertQueryColumnName(String columnName) {
        if ("hasDel".equals(columnName)) {
            return "hasDelEq";
        }
        return columnName;
    }

    private static final Set<String> blackUpdateColumnSet = Sets.newHashSet(
            "id",
            "creator",
            "createTime");

    private static void printUpdateById() {
        System.out.printf("\t<update id=\"updateById\" parameterType=\"%s\">\n", PO_NAME);
        System.out.printf("\t\tupdate %s\n", TABLE_NAME);
        System.out.print("\t\t<set>\n");


        for (int i = 0, size = COLUMN_LIST.size(); i < size; i++) {
            String[] array = COLUMN_LIST.get(i).split(",");
            String columnName = array[0];
//            String columnType = getColumnType(array[1]);

            if (blackUpdateColumnSet.contains(columnName)) {
                continue;
            }

            System.out.printf("\t\t\t<if test=\"%s != null\">\n" +
                    "                %s = #{%s},\n" +
                    "            </if>\n", columnName, columnName, columnName);
        }
        System.out.printf("\t\t</set>\n");
        System.out.printf("\t\twhere id = #{id}\n");
        System.out.printf("\t</update>\n");
    }
}